#include "net/Event.hxx"
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include <queue>

using namespace kiwii::net;
using namespace std;

TEST(TimeEventUsedInPriorityQueue, Seconds) {
  priority_queue<TimeEvent> pq;
  TimeEvent te(1, 0);

  te.id_ = 1;
  te.whenSeconds_ = 100;
  pq.push(te);
  te.id_ = 2;
  te.whenSeconds_ = 20;
  pq.push(te);
  te.id_ = 3;
  te.whenSeconds_ = 30;
  pq.push(te);

  EXPECT_EQ(2, pq.top().id_);
  pq.pop();
  EXPECT_EQ(3, pq.top().id_);
  pq.pop();
  EXPECT_EQ(1, pq.top().id_);
}

TEST(TimeEventUsedInPriorityQueue, Milliseconds) {
  priority_queue<TimeEvent> pq;
  TimeEvent te(1, 0);

  te.whenSeconds_ = 1;
  te.id_ = 1;
  te.whenMilliseconds_ = 300;
  pq.push(te);
  te.id_ = 2;
  te.whenMilliseconds_ = 100;
  pq.push(te);
  te.id_ = 3;
  te.whenMilliseconds_ = 500;
  pq.push(te);

  EXPECT_EQ(2, pq.top().id_);
  pq.pop();
  EXPECT_EQ(1, pq.top().id_);
  pq.pop();
  EXPECT_EQ(3, pq.top().id_);
  EXPECT_EQ((unsigned)1, pq.size());
}

TEST(TimeEvent, Timeout) {
  TimeEvent te(100, 0); //100 milliseconds
  usleep(50 * 1000); //sleep 50 milliseconds
  struct timeval tv = te.timeout();
  EXPECT_EQ(0, tv.tv_sec);
  EXPECT_LT(tv.tv_usec, 50 * 1000);
  EXPECT_GE(tv.tv_usec, 0);
  //std::cout << tv.tv_sec << ":" << tv.tv_usec << std::endl;
}

TEST(TimeEvent, Expired) {
  TimeEvent te(100, 0);
  usleep(50 * 1000);
  EXPECT_FALSE(te.isExpired());
  usleep(50 * 1000);
  EXPECT_TRUE(te.isExpired());
}
